package model;

import java.sql.SQLException;
import java.util.ArrayList;

/**
 * Das BenutzerRepository repräsentiert die Datenbank.
 * 
 * @author Jonas Gutermuth, David Caroli, Daniel Eischer
 */
@SuppressWarnings("serial")
public class BenutzerRepository extends ArrayList<Benutzer> {

	/** Instanz des Benutzerrepository. */
	private static BenutzerRepository benutzerRepository = null;

	/** Die Datenbankschnittstelle. */
	private static DatenbankSchnittstelle datenbankSchnittstelle;

	/**
	 * Stellt die Verbindung zur Datenbank her und füllt sich selber mit
	 * Einträgen.
	 * 
	 * @throws ClassNotFoundException
	 *             the class not found exception
	 * @throws SQLException
	 *             Wirft eine SQL Exception
	 */
	private BenutzerRepository() throws ClassNotFoundException, SQLException {
		datenbankSchnittstelle = DatenbankSchnittstelle.getInstance();
		addArray(datenbankSchnittstelle.getBenutzer());
		System.out.println("Benutzer Repository geladen");
	}

	/**
	 * Fügt ein Benutzer-Array der Arraylist hinzu (Wichtig bei der Datenbankinitialisierung).
	 * 
	 * @param benutzer die zu speichernden Benutzer
	 */
	private void addArray(Benutzer[] benutzer) {
		for (int i = 0; i < benutzer.length; i++) {
			this.add(benutzer[i]);
		}
	}

	/**
	 * Speichert den übergebenen Benutzer in der Datenbank und im Repository
	 * (für Benutzeränderungen).
	 * 
	 * @param benutzer der zu speichernde Benutzer
	 * @throws SQLException
	 * @throws ClassNotFoundException 
	 * @throws IllegalArgumentException 
	 */
	public void saveBenutzer(Benutzer benutzer) throws SQLException, IllegalArgumentException, ClassNotFoundException {
		String[][] db_werte = new String[2][5];
		// spaltennamen
		db_werte[0][0] = "erstellt";
		db_werte[0][1] = "email";
		db_werte[0][2] = "nachname";
		db_werte[0][3] = "vorname";
		db_werte[0][4] = "passwort";
		// werte
		db_werte[1][0] = "" + benutzer.getErstellt();
		db_werte[1][1] = benutzer.getEmail();
		db_werte[1][2] = benutzer.getNachname();
		db_werte[1][3] = benutzer.getVorname();
		db_werte[1][4] = benutzer.getPasswort();

		// Datenbank updaten
		datenbankSchnittstelle.update("benutzer", "id=" + benutzer.getId(), db_werte);

	}

	/**
	 * Erstellt einen neuen Benutzer.
	 * 
	 * @param benutzer
	 *            der zu erstellende Benutzer
	 * @throws SQLException
	 * @throws ClassNotFoundException 
	 */
	public void newBenutzer(Benutzer benutzer) throws SQLException, ClassNotFoundException {
		String[][] db_werte = new String[2][5];
		// spaltennamen
		db_werte[0][0] = "erstellt";
		db_werte[0][1] = "email";
		db_werte[0][2] = "nachname";
		db_werte[0][3] = "vorname";
		db_werte[0][4] = "passwort";
		// werte
		db_werte[1][0] = "" + benutzer.getErstellt();
		db_werte[1][1] = benutzer.getEmail();
		db_werte[1][2] = benutzer.getNachname();
		db_werte[1][3] = benutzer.getVorname();
		db_werte[1][4] = benutzer.getPasswort();
		// Datenbank updaten
		benutzer.setId(datenbankSchnittstelle.insert("benutzer", db_werte));
		this.add(benutzer);
	}

	/**
	 * Löscht einen Benutzer.
	 * 
	 * @param benutzer der Benutzer
	 * @throws SQLException
	 * @throws ClassNotFoundException
	 */
	public void delBenutzer(Benutzer benutzer) throws SQLException,
			ClassNotFoundException {
		if (benutzer != null) {
			// aus Gruppen löschen
			GruppenRepository gruppenRepository = GruppenRepository.getInstance();
			Benutzer[] member, memberNeu;
			for (int i = 0; i < gruppenRepository.size(); i++) {
				if (gruppenRepository.get(i).inGruppe(benutzer.getId())) {
					member = gruppenRepository.get(i).getBenutzer();
					memberNeu = null;
					if (member != null) {
						memberNeu = new Benutzer[member.length - 1];
						for (int j = 0; j < member.length; j++) {
							if (member[j] != benutzer) {
								memberNeu[j] = member[j];
							} else {
								for (j = j + 1; j < member.length; j++) {
									memberNeu[j - 1] = member[j];
								}
								break;
							}
						}
					}
					gruppenRepository.get(i).setBenutzer(memberNeu);
					gruppenRepository.saveGruppe(gruppenRepository.get(i));
				}
			}
			// aus Ebenen löschen
			EbenenRepository ebenenRepository = EbenenRepository.getInstance();
			for (int i = 0; i < ebenenRepository.size(); i++) {
				// aus Verantwortlich löschen
				member = ebenenRepository.get(i).getVerantwortlich();
				if (member != null) {
					for (int h = 0; h < member.length; h++) { // ist nutzer verantwortlicher der ebene?
						if (member[h] == benutzer) { // nutzer aus verantwortlichen entfernen
							memberNeu = null;
							memberNeu = new Benutzer[member.length - 1];
							for (int j = 0; j < member.length; j++) {
								if (member[j] != benutzer) {
									memberNeu[j] = member[j];
								} else {
									for (j = j + 1; j < member.length; j++) {
										memberNeu[j - 1] = member[j];
									}
									break;
								}
							}
							ebenenRepository.get(i).setVerantwortlich(memberNeu);
							break;
						}
					}
				}

				// aus Redakteuren löschen
				member = ebenenRepository.get(i).getRedakteur();
				if (member != null) {
					for (int h = 0; h < member.length; h++) { // ist nutzer redakteur der ebene?
						if (member[h] == benutzer) { // nutzer aus redakteur entfernen
							memberNeu = null;
							memberNeu = new Benutzer[member.length - 1];
							for (int j = 0; j < member.length; j++) {
								if (member[j] != benutzer) {
									memberNeu[j] = member[j];
								} else {
									for (j = j + 1; j < member.length; j++) {
										memberNeu[j - 1] = member[j];
									}
									break;
								}
							}
							ebenenRepository.get(i).setRedakteur(memberNeu);
							break;
						}
					}
				}
			}
			// aus Datenbank löschen
			datenbankSchnittstelle.del("benutzer", "id='" + benutzer.getId()+ "'");
						
			// aus Array löschen
			for (int i = 0; i < this.size(); i++) {
				if (this.get(i) == benutzer) {
					this.remove(i);
					this.trimToSize();
				}
			}
		}
	}

	/**
	 * Liefert einen Benutzer nach ID zurück.
	 * 
	 * @param id
	 *            die ID, nach der ein benutzer gesucht wird
	 * @return <code>null</code>, falls kein Benutzer mit gegebener ID gefunden
	 *         wurde, ansonsten der Benutzer
	 */
	public Benutzer getBenutzerNachId(int id) {
		for (int i = 0; i < this.size(); i++) {
			if (this.get(i).getId() == id) {
				return this.get(i);
			}
		}
		return null;
	}

	/**
	 * Überprüft das Passwort und die E-Mail. Wenn erfolgreich wird der Benutzer
	 * zurückgegeben.
	 * 
	 * @param email
	 *            die zu prüfende Emailadresse des Benutzers
	 * @param passwort
	 *            das zu prüfende Passwort des Benutzers
	 * @return <code>null</code>, falls kein Benutzer mit Übereinstimmung von
	 *         Emailadresse und passowrt gefunden wurde, ansonsten der Benutzer
	 */
	public Benutzer login(String email, String passwort) {
		System.out.println(email + " " + passwort);
		Benutzer b = getBenutzerNachEmail(email);
		if (b != null) {
			if (b.getPasswort().equals(passwort)) {
				return b;
			}
		}
		return null;
	}

	/**
	 * Suchen eines Benutzers nach dessen E-Mail-Adresse
	 * 
	 * @param email
	 *            Die E-Mail
	 * @return <code>null</code>, falls kein Benutzer mit gegebener Emailadresse
	 *         gefunden wurde, ansonsten der Benutzer
	 */
	public Benutzer getBenutzerNachEmail(String email) {
		for (int i = 0; i < this.size(); i++) {
			if (this.get(i).getEmail().equals(email)) {
				return this.get(i);
			}
		}
		return null;
	}

	/**
	 * Gibt die (einmalig vorhandene) Instanz des BenutzerRepository zurück.
	 * 
	 * @return Instanz des BenutzerRepository
	 * @throws ClassNotFoundException
	 *             Classe nicht gefunden
	 * @throws SQLException
	 *             SQL Exception
	 */
	public static BenutzerRepository getInstance()
			throws ClassNotFoundException, SQLException {
		if (benutzerRepository == null) {
			benutzerRepository = new BenutzerRepository();
		}
		return benutzerRepository;
	}
}
